const UserBaseSchema = require('../entity/user/userbase');
const VipLevelSchema = require('../entity/user/viplevel');
const AddressSchema = require('../entity/user/address');

const wxUserApi = require('./weixin/user');
const tokenSvc = require('./token');
const userError = require('../module/error/user');

const promoteService = require('./promoteService');
const ChargeAccount = require('../entity/charge/chargeaccount');
const { SchemaTypes } = require('../entity/schema');

function getRandomNumberBySeed (seed) {
    seed = (seed * 9301 + 49297) % 233280;
    return seed / (233280.0);
}

// =========================== 用户登录流程 ===============================
// 微信登录
async function wxUserLogin (wxCode) {
    const result = await wxUserApi.code2Session(wxCode);
    if (result.errcode && result.errcode !== 0) {
        throw new userError.WxLoginFail(result.errmsg);
    }
    return userLogin(result.openid, result.session_key);
}
async function userLogin (openId, sessionKey) {
    const userBaseModel = new UserBaseSchema();

    if (!await userBaseModel.existUser(openId)) {
        const VipLevelModel = new VipLevelSchema().getModel();
        const vipInfo = await VipLevelModel.findOne({ isDefault: true });
        const defaultNickname = '用户' + parseInt(getRandomNumberBySeed(new Date().getTime()) * Math.pow(10, 7));
        const userData = await userBaseModel.insertUserData(openId, sessionKey, vipInfo._id, defaultNickname);

        // 初始化用户推广账户
        await promoteService.initPromoteAccount(userData._id);
    }

    const userId = await userBaseModel.getUserIdByOpenId(openId);
    await userBaseModel.updateSessionKey(userId, sessionKey);
    return tokenSvc.generateMiniProgramToken({ userId });
}

// 更新用户数据avatar + nickname
async function updateUserData (userId, nickname, avatar) {
    const userBaseModel = new UserBaseSchema();
    await userBaseModel.updateUserData(userId, nickname, avatar || '');
    return 1;
}
// 更新用户手机号
async function updateUserPhone (userId, encryptedData, iv) {
    const userBaseEntity = new UserBaseSchema();
    const userData = await userBaseEntity.getModel().findById(userId);
    const phone = await wxUserApi.decodeUserPhone(userData.session_key, encryptedData, iv);
    await userBaseEntity.updateUserPhone(userId, phone);
    return phone;
}

// 设置默认地址
async function setDefaultAddress (userId, areaId, addressId) {
    const AddressModel = new AddressSchema().getModel();
    await AddressModel.updateMany({ areaId, userId }, { isDefault: false });
    await AddressModel.findByIdAndUpdate(addressId, { isDefault: true });
    return 1;
}

// =========================== 查询用户信息 ===============================
// 获取用户信息
async function getUserInfo (userId) {
    const userBaseEntity = new UserBaseSchema();
    const userInfo = await userBaseEntity.getUserData(userId);
    const VipLevelModel = new VipLevelSchema().getModel();
    const vipInfo = await VipLevelModel.findById(userInfo.vip_id);
    if (userInfo) {
        return {
            ...userInfo.toObject(),
            description: vipInfo.description,
            discount: vipInfo.discount
        };
    }
    return {};
}
async function getUserIdByOpenId (openId) {
    const UserBaseEntity = new UserBaseSchema();
    return UserBaseEntity.getUserIdByOpenId(openId);
}
async function getUserInfoByPhone (phone) {
    const userBaseEntity = new UserBaseSchema();
    const userInfo = await userBaseEntity.getModel().findOne({ phone: phone });
    if (userInfo) {
        return {
            ...userInfo.toObject()
        };
    }
    return {};
}
async function getUserInfoByNickname (nickname) {
    const userBaseEntity = new UserBaseSchema();
    const userInfo = await userBaseEntity.getModel().findOne({ nickname: { $regex: nickname } });
    if (userInfo) {
        return userInfo.toObject();
    }
    return null;
}
async function findUserByPhone (phone) {
    const userBaseEntity = new UserBaseSchema();
    return userBaseEntity.getModel().findOne({ phone: phone });
}

// 增加用户积分（积分系统已无效）
async function addUserScore (userId, score) {
    const userModel = new UserBaseSchema().getModel();
    await userModel.findByIdAndUpdate(userId, { $inc: { score: score } });
}
module.exports = {
    wxUserLogin,
    updateUserData,
    getUserInfo,
    updateUserPhone,
    getUserInfoByPhone,
    findUserByPhone,
    getUserInfoByNickname,
    getUserIdByOpenId,
    setDefaultAddress,
    addUserScore
};
